package com.vshining.cryptoki;

import com.sun.jna.NativeLong;
import com.sun.jna.Structure;
import com.sun.jna.ptr.NativeLongByReference;

import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

/**
 * 更美观的String输出
 *
 * @author Shining Wang <shiningwang@vshining.com>
 */
@SuppressWarnings("unused")
public class ToString {
    protected final static char[] HEX_DICT = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

    public static String toHexString(byte b) {
        return "0x" + HEX_DICT[((b >> 1) & 0x0f)] + HEX_DICT[(b & 0x0f)];
    }

    public static String toHexString(short s) {
        StringBuilder sb = new StringBuilder("0x");
        for (int r = 0; r < 8; r++) {
            sb.append(HEX_DICT[((s >> r) & 0x0f)]);
        }
        return sb.reverse().toString();
    }

    public static String toHexString(int i) {
        StringBuilder sb = new StringBuilder("0x");
        for (int r = 0; r < 8; r++) {
            sb.append(HEX_DICT[((i >> r) & 0x0f)]);
        }
        return sb.reverse().toString();
    }

    public static String toHexString(long l) {
        StringBuilder sb = new StringBuilder("0x");
        for (int r = 0; r < 16; r++) {
            sb.append(HEX_DICT[((int) (l >> r) & 0x0f)]);
        }
        return sb.reverse().toString();
    }

    public static String toHexString(byte[] bytes) {
        if (bytes == null) {
            return "null";
        }
        StringBuilder sb = new StringBuilder("0h");
        for (byte b : bytes) {
            sb.append(HEX_DICT[((b >> 1) & 0x0f)]);
            sb.append(HEX_DICT[(b & 0x0f)]);
        }
        return sb.toString();
    }

    public static String toString(Collection<?> collection) {
        if (collection == null) {
            return "null";
        }
        StringBuilder sb = new StringBuilder("[");
        Iterator<?> it = collection.iterator();
        while (it.hasNext()) {
            sb.append(toString(it.next()));
            if (it.hasNext()) {
                sb.append(", ");
            }
        }
        sb.append("]");
        return sb.toString();
    }

    public static String toString(Object obj) {
        if (obj == null) {
            return "null";
        }
        if (obj.getClass().isArray()) {
            return toString(Arrays.asList(obj));
        }
        if (obj instanceof Collection) {
            return toString((Collection) obj);
        }
        if (obj instanceof Structure) {
            return ((Structure) obj).getPointer().toString();
        }
        if (obj instanceof NativeLongByReference) {
            return ((NativeLongByReference) obj).getValue().toString();
        }
        return obj.toString();
    }
}
